<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>手写显示绑定函数</title>
</head>
<body>
    <script>
       
       let person = {
        name:"cq",
        age:"18",
        height:1.88
       }
        function foo()
        {
             console.log(this);
        }
       //原来的call绑定
       foo.call(person);

       //实现自己的绑定函数
       Function.prototype.cqCall = function (thisArg,...args)
       {
           //将thisArg转换为一定合法的对象
           thisArg = (thisArg === null||thisArg === undefined)?window:Object(thisArg);
           //绑定this
           Object.defineProperty(thisArg,"fn",{
            configurable:true,
            enumerable:false,
            value:this
           })
           thisArg.fn(...args);
           delete thisArg.fn
       }

       //实现apply
      Function.prototype.Cqapply = function(thisArg,args = [])
      {
          //确保传入的是数组
           if(!Array.isArray(args)&&args.length!=0)
           {
             throw Error();
           }

          //确保thisArg的正确性
           thisArg = (thisArg === null||thisArg ===undefined)?window:Object(thisArg);
          //绑定函数的this
          Object.defineProperty(thisArg,"fn",{
            configurable:true,
            enumerable:false,
            value:this
          })

          thisArg.fn(...args);
          delete thisArg.fn;
      }

      //实现bind
      Function.prototype.Cqbind = function(thisArg,...args)
      {
         thisArg = (thisArg===null||thisArg === undefined)?window:Object(thisArg);
         
         Object.defineProperty(thisArg,"fn",{
             configurable:true,
             enumerable:false,
             value:this
         })
         
         //bind返回一个新的函数，新的函数可能被放入新的参数
         return function(...newArgs)
         {
            let allArgs = [...args,...newArgs];
            thisArg.fn(...allArgs);
         }
      }
       const exe = foo.Cqbind(person);
       exe();
       exe();
       foo.cqCall(person);
       foo.Cqapply(person);
      
    //    names = ["cq","cq1"];
    //    console.log(typeof names);

    </script>
</body>
</html>